package com.usian.article.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.usian.article.entity.ApArticle;
import com.usian.article.entity.ApArticleContent;
import com.usian.article.entity.ApAuthor;
import com.usian.article.entity.ApCollection;
import com.usian.article.mapper.ApArticleMapper;
import com.usian.article.service.IApArticleContentService;
import com.usian.article.service.IApArticleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.usian.article.service.IApAuthorService;
import com.usian.article.service.IApCollectionService;
import com.usian.behavior.client.BehaviorFeign;
import com.usian.common.enums.AppHttpCodeEnum;
import com.usian.common.exception.LeadException;
import com.usian.common.threadlocal.UserThreadLocalUtils;
import com.usian.common.util.BeanHelper;
import com.usian.model.article.dtos.ArticleDto;
import com.usian.model.article.dtos.ArticleHomeDto;
import com.usian.model.article.dtos.ArticleInfoDto;
import com.usian.model.media.dtos.WmNewsResultDTO;
import com.usian.user.client.UserFeign;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 文章信息表，存储已发布的文章 服务实现类
 * </p>
 *
 * @author usian
 * @since 2022-10-07
 */
@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements IApArticleService {

    @Autowired
    private IApAuthorService apAuthorService;

    @Autowired
    private IApArticleContentService apArticleContentService;

    @Override
    @Transactional
    public Long saveArticle(WmNewsResultDTO dto) {
        //组装ApArticle数据
        ApArticle apArticle = new ApArticle();
        apArticle.setTitle(dto.getTitle());
        //根据自媒体用户id查询作者信息
        ApAuthor apAuthor = apAuthorService.findByWmUserId(dto.getWmUserId());
        apArticle.setAuthorId(apAuthor.getId());
        apArticle.setAuthorName(apAuthor.getName());
        apArticle.setChannelId(dto.getChannelId());
        apArticle.setChannelName(dto.getChannelName());
        apArticle.setLayout(dto.getType());
        apArticle.setFlag(0);
        apArticle.setImages(dto.getImages());
        apArticle.setLabels(dto.getLabels());
        apArticle.setCreatedTime(new Date());
        apArticle.setPublishTime(dto.getPublishTime());
        apArticle.setIsComment(true);
        apArticle.setIsForward(true);
        apArticle.setIsDelete(false);
        apArticle.setIsDown(false);
        apArticle.setWmNewsId(dto.getId());
        //保存ApArticle文章数据
        boolean b = this.save(apArticle);
        if(!b){
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR,"保存app文章失败");
        }

        //组装ApArticleContent数据
        ApArticleContent apArticleContent = new ApArticleContent();
        apArticleContent.setArticleId(apArticle.getId());
        apArticleContent.setContent(dto.getContent());
        //保存ApArticleContent文章数据
        boolean b1 = apArticleContentService.save(apArticleContent);
        if(!b1){
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR,"保存app文章内容失败");
        }

        return apArticle.getId();
    }

//    修改文章上下架状态
    @Override
    public void updateIsDown(Map<String, Integer> map) {
        UpdateWrapper<ApArticle> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(ApArticle::getWmNewsId,map.get("wmNewsId"))
                .set(ApArticle::getIsDown,map.get("enable")==0?true:false);
        boolean b = update(updateWrapper);
        if(!b){
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR,"更新上下架状态失败");
        }
    }

//    首页文章加载
    @Override
    public List<ArticleDto> load(ArticleHomeDto dto, int type) {
//        参数校验
        if (dto==null){
            throw new LeadException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
//        设置分页条件
        Integer size = dto.getSize();
        if (size==null || size==0){
            size=10;
        }
        Page<ApArticle> page = new Page<>(1,size);
//        设置查询条件
        String tag = dto.getTag();
        QueryWrapper<ApArticle> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(dto.getTag()) && !"__all__".contains(tag)){
            queryWrapper.lambda().eq(ApArticle::getChannelId,tag);
        }
        //根据type类型设置发布时间条件
        if (type==1){
            //加载更多信息
            queryWrapper.lambda().lt(ApArticle::getCreatedTime,dto.getMinBehotTime());
        }else {
            //加载最新信息
            queryWrapper.lambda().gt(ApArticle::getCreatedTime,dto.getMaxBehotTime());
        }
        //非下架，非删除状态的文章
        queryWrapper.lambda().
                eq(ApArticle::getIsDown,false).
                eq(ApArticle::getIsDelete,false);
//        根据发布时间排序
        queryWrapper.lambda().orderByDesc(ApArticle::getCreatedTime);
//        执行查询
        IPage<ApArticle> iPage = this.page(page, queryWrapper);
//        组装查询结果
        List<ApArticle> records = iPage.getRecords();
        if (CollectionUtils.isEmpty(records)){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
//        数据转换为DTO类型
        List<ArticleDto> articleDtoList = BeanHelper.copyWithCollection(records, ArticleDto.class);
        return articleDtoList;
    }


//    根据文章id查询文章详情
    @Override
    public Map<String, Object> loadArticleInfo(ArticleInfoDto dto) {
//        参数校验
        if (dto==null){
            throw new LeadException(AppHttpCodeEnum.PARAM_INVALID);
        }
//        查询文章数据
        QueryWrapper<ApArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ApArticle::getId,dto.getArticleId())
                .eq(ApArticle::getIsDelete,false)
                .eq(ApArticle::getIsDown,false);
        ApArticle apArticle = this.getOne(queryWrapper);
        if (apArticle==null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
//        查询文章内容数据
        QueryWrapper<ApArticleContent> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.lambda().eq(ApArticleContent::getArticleId,dto.getArticleId());
        ApArticleContent articleContent = apArticleContentService.getOne(queryWrapper2);
        if (articleContent==null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        Map<String,Object> map = new HashMap<>();
        map.put("config",apArticle);
        map.put("content",articleContent);
        return map;
    }


    @Autowired
    public IApCollectionService apCollectionService;

    @Autowired
    private BehaviorFeign behaviorFeign;

    @Autowired
    private UserFeign userFeign;
    /**
     * 加载文章详情的行为内容
     * @param dto
     * @return
     */
    @Override
    public Map<String, Boolean> loadArticleBehavior(ArticleInfoDto dto) {
//        判断是用户操作还是设备操作
        Boolean isUser = false;
        //从线程中获取用户id
        Integer userId = UserThreadLocalUtils.getUserId();
        if (userId==null && dto.getEquipmentId()==null){
            throw new LeadException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        if (userId!=null){
            //用户操作
            isUser=true;
        }
//        查询当前文章是否被收藏
        QueryWrapper<ApCollection> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ApCollection::getArticleId,dto.getArticleId())
                             .eq(ApCollection::getType,0);
        if (isUser){
            //用户收藏
            queryWrapper.lambda().eq(ApCollection::getApUserId,userId);
        }else {
            //设备收藏
            queryWrapper.lambda().eq(ApCollection::getEquipmentId,dto.getEquipmentId());
        }
        int count = apCollectionService.count(queryWrapper);
        Boolean isCollection=false;
        if (count>0){
            isCollection=true;
        }
//        远程调用行为微服务，查询点赞及不喜欢
        Map<String, Boolean> map = behaviorFeign.findBehavior(userId, dto.getEquipmentId(), dto.getArticleId(), 0);
//        远程调用用户微服务，查询是否关注行为
        Boolean isFollow = false;
        if (isUser){
            //用户登录了
            //根据作者id，查询作者社交账号id
            ApAuthor apAuthor = apAuthorService.getById(dto.getAuthorId());
            if (apAuthor!=null){
                Integer followId=apAuthor.getUserId();
                isFollow = userFeign.findByUserIdAndFollowId(userId, followId);
            }

        }
//        封装结果并返回
        map.put("iscollection",isCollection);
        map.put("isfollow",isFollow);
        return map;
    }


//    分页查询文章信息
    @Override
    public List<ArticleDto> findArticleByPage(int page, int size) {
//        设置分页条件
        Page<ApArticle> apArticlePage = new Page<>(page,size);
//        设置查询条件(非下架非删除)
        QueryWrapper<ApArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ApArticle::getIsDown,false)
                             .eq(ApArticle::getIsDelete,false);
//        执行查询
        IPage<ApArticle> iPage = this.page(apArticlePage, queryWrapper);
        List<ApArticle> records = iPage.getRecords();
        if (!CollectionUtils.isEmpty(records)){
            //数据转换
            List<ArticleDto> articleDtoList = BeanHelper.copyWithCollection(records, ArticleDto.class);
            return articleDtoList;
        }
        return null;
    }
}
